﻿#Requires -RunAsAdministrator

param
(
	[parameter(Mandatory = $true)]
	[ValidateNotNullOrEmpty()]
	[String]$rootDirectory
)

<#
powershell简易文件服务器。
无安全，无认证。
http://localhost
支持win+powershell v5 ，支持win+powershellv7，支持linux。
默认监听locahost：80端口。由于端口小于1024，所以需要管理员权限启动。
#问：这个脚本谁写的？有问题找谁技术支持？
#答：QQ群号=183173532
#名称=powershell脚本之巅
#华之夏，脚之巅，有我ps1片天！
#专门教学win，linux通用的ps1脚本。不想学也可以，入群用红包求写脚本。
#>

# 设置根目录,不支持子目录。
if (Test-Path -LiteralPath $rootDirectory)
{
}
else
{
	Write-Error "错误：找不到：${rootDirectory} ，退出码1"
	exit 1
}

# 创建 HTTP 监听器
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://*:80/")
$listener.Start()
Write-Host "HTTP 服务器已启动，监听端口 80..."

try
{
	while ($listener.IsListening)
	{
		# 等待请求
		$context = $listener.GetContext()
		$request = $context.Request
		$response = $context.Response

		# 获取请求的 URL 路径
		$urlPath = $request.Url.LocalPath.TrimStart('/')

		# 如果请求根目录，列出文件
		if ($urlPath -eq "")
		{
			$files = Get-ChildItem -Path $rootDirectory -File
			$html = '<html><head>
	<meta charset="UTF-8">
	<title>二进制文件下载</title>
        </head><body><h1>文件列表</h1><ul>'
			foreach ($file in $files)
			{
				$fileUrl = "http://$($request.UserHostAddress)/$($file.Name)"
				$html += "<li><a href='$fileUrl'>$($file.Name)</a></li>"
			}
			$html += "</ul></body></html>"
			$buffer = [System.Text.Encoding]::UTF8.GetBytes($html)
			$response.ContentType = "text/html"
			$response.ContentLength64 = $buffer.Length
			$response.OutputStream.Write($buffer, 0, $buffer.Length)
		}
		else
		{
			# 处理文件下载请求
			$filePath = Join-Path -Path $rootDirectory -ChildPath $urlPath
			if (Test-Path $filePath -PathType Leaf)
			{
				$fileBytes = [System.IO.File]::ReadAllBytes($filePath)
				$response.ContentType = "application/octet-stream"
				$response.ContentLength64 = $fileBytes.Length
				$response.OutputStream.Write($fileBytes, 0, $fileBytes.Length)
			}
			else
			{
				$response.StatusCode = 404
				$buffer = [System.Text.Encoding]::UTF8.GetBytes("文件未找到")
				$response.ContentLength64 = $buffer.Length
				$response.OutputStream.Write($buffer, 0, $buffer.Length)
			}
		}

		# 关闭响应
		$response.Close()
		Start-Sleep -Milliseconds 500
	}
}
finally
{
	$listener.Stop()
}

